package airportCoordination;

import java.util.ListIterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.locks.Lock;

import org.json.JSONObject;


public class ErrorControl implements Runnable{
	
	private List<PacketLog> logbox;
	private Lock lock;
	
	private final int TIMEOUT = 5;
	private BlockingQueue<Cargo> mailbox;
	
	public ErrorControl(List<PacketLog> lb, Lock l, BlockingQueue<Cargo> mb)
	{
		logbox = lb;
		lock = l;
		mailbox = mb;
	}
	
	public void run()
	{
		while(true)
		{
			try{
				Thread.sleep(5000);
			}catch(Exception e){ System.out.print("FATAL ERROR. Error trying to sleep ErrorControl thread: " + e.getMessage() + "\n"); System.exit(666); }
			
			LinkedList<PacketLog> toSend = new LinkedList<PacketLog>();
			PacketLog packet;
			
			lock.lock();
			ListIterator<PacketLog> iter=(ListIterator<PacketLog>)logbox.iterator();
			while (iter.hasNext())
			{
				packet = iter.next();
				if (packet.timedout(TIMEOUT) && packet.is_ping())
				{
					JSONObject msg = null;
					String message = null;
					try{
						msg = new JSONObject();
						msg.put("type", "UNPLUG");
						msg.put("ip", packet.get_ip());
						msg.put("id", 0);
						message = msg.toString();
					}catch(Exception e){ System.out.print("Error generating unplug message: " + e.getMessage() + "\n"); continue; }
					
					try{ mailbox.put(new Cargo(message, packet.get_ip())); }catch(Exception e){ System.out.print("Error sending unplug to mailbox: " + e.getMessage() + "\n"); }
					
					iter.remove();
				}
				else if (packet.timedout(TIMEOUT) || packet.error())
				{
					iter.set(new PacketLog(packet));
					toSend.add(packet);
				}
			}
			lock.unlock();
			
			iter=(ListIterator<PacketLog>)toSend.iterator();
			while (iter.hasNext())
			{
				packet = iter.next();
				Sender.send_packet(packet.get_ip(), packet.get_port(), packet.get_msg());
			}
		}
	}
}
